package com.lvmama.rhino.web.comment.product.controller;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.lvmama.rhino.pojo.comment.Enum.EnumForCategory;
import com.lvmama.rhino.pojo.comment.Enum.EnumForComment;
import com.lvmama.rhino.pojo.comment.entity.ProductCommentAnalysis;
import com.lvmama.rhino.pojo.comment.entity.ProductCommentDetail;
import com.lvmama.rhino.pojo.comment.query.ProductRankPageQuery;
import com.lvmama.rhino.pojo.comment.query.ProductViewPointRankQuery;
import com.lvmama.rhino.pojo.comment.response.CommentTendencyResponse;
import com.lvmama.rhino.pojo.comment.response.ProductViewPointRankResponse;
import com.lvmama.rhino.service.comment.ProductAnalysisService;
import com.lvmama.rhino.service.comment.ProductCommentDetailService;
import com.lvmama.rhino.service.impl.comment.RedisServiceImpl;
import com.lvmama.rhino.utils.Constants;
import com.lvmama.rhino.utils.DateUtil;
import net.sf.json.JSONArray;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.github.pagehelper.PageInfo;

/**
 * Created by hejing on 2017/9/6.
 */
@Controller
@RequestMapping("productComment")
public class ProductController {

    private Logger log = Logger.getLogger(ProductController.class);

    @Autowired
    private ProductAnalysisService productAnalysisService;

    @Autowired
    private ProductCommentDetailService productCommentDetailService;

    @Autowired
    private RedisServiceImpl redisService;

    @RequestMapping(value = "productAnalysis", method = RequestMethod.GET)
    public String commentList(ModelMap model, ProductRankPageQuery query) {
        log.info("request commentList start.");
        PageInfo<ProductCommentAnalysis> productRankPage = new PageInfo<>();
        String productRankPageStr;
        try {
            String key = redisService.getKey("productAnalysis");
            // 品类
            EnumForCategory[] categories = EnumForCategory.getAllCategory();
            model.put("categories", categories);
            if (null == query.getSelectedTime() && null == query.getChooseTime()) {
                query.setDays(7);
                query.setSelectedTime(7);
            }
            // 先查询redis
            if (isProductAnalysisQueryRedis(query)) {
                log.info("request commentList redis query start");
                productRankPageStr = redisService.getObjectValue(key);
                log.info("request commentList redis query end");
                if (StringUtils.isNotBlank(productRankPageStr)) {
                    productRankPage = new Gson().fromJson(productRankPageStr, new TypeToken<PageInfo<ProductCommentAnalysis>>() {}.getType());
                } else {
                    productRankPage = queryCommentList(query);
                    redisService.setValueExpire(key, productRankPage, Constants.TIMEOUT);
                }
            } else {
                productRankPage = queryCommentList(query);
            }
        } catch (Exception e) {
            log.error("request commentList redis query error:" + e.getMessage(), e);
            try {
                log.info("request commentList mysql requery start");
                productRankPage = queryCommentList(query);
                log.info("request commentList mysql requery end");
            } catch (Exception e1) {
                e1.printStackTrace();
                log.error("request commentList mysql requery error:" + e1.getMessage(), e1);
            }
        }

        try {
            model.put("productRankPage", productRankPage);
            if (StringUtils.isNotBlank(query.getCategoryName())) {
                String categoryId = EnumForCategory.getCategoryValueByShowName(query.getCategoryName());
                query.setCategoryId(categoryId);
            }
            //回显查询条件
            model.put("query", query);
            model.put("chooseTime", query.getChooseTime());
            String commentTypeName = query.getCommentTypeName();
            if (StringUtils.isNotBlank(commentTypeName)) {
                model.put("commentType", EnumForComment.getCommentValue(commentTypeName));
            }
            model.put("flag", query.getFlag());
        } catch (Exception e) {
            e.printStackTrace();
            log.error("request commentList analyze error:" + e.getMessage(), e);
        }
        log.info("request commentList end.");
        return "application/productComment/productAnalysis";
    }

    /**
     * 查询评论列表
     *
     * @param query
     * @return PageInfo<ProductCommentAnalysis>
     * @throws Exception
     */
    private PageInfo<ProductCommentAnalysis> queryCommentList(ProductRankPageQuery query) throws Exception {
        log.info("request commentList queryCommentList query start");
        PageInfo<ProductCommentAnalysis> productRankPage = productAnalysisService.getProductRankPage(query);
        log.info("request commentList queryCommentList query end");
        return productRankPage;
    }

    /**
     * 产品评价分析
     * 7天内的数据查询redis(第一页&无查询条件)
     *
     * @param query
     * @return
     */
    private boolean isProductAnalysisQueryRedis(ProductRankPageQuery query) {
        if (((null != query.getDays() && 7 == query.getDays()) ||
                (null != query.getSelectedTime() && 7 == query.getSelectedTime()))
                && (query.getCurrentPage() == 1)
                && (StringUtils.isBlank(query.getProductId()))
                && (StringUtils.isBlank(query.getCategoryId()))) {
            return true;
        }
        return false;
    }

    /**
     * 产品评价排名
     * 7天内的数据查询redis(第一页&无查询条件)
     *
     * @param param
     * @return
     */
    private boolean isProductRankQueryRedis(ProductRankPageQuery param) {

        String dataFormat = "yyyyMMdd";
        SimpleDateFormat sdf = new SimpleDateFormat(dataFormat);
        String startTime = sdf.format(param.getStartTime());
        String endTime = sdf.format(param.getEndTime());
        String beginDate = sdf.format(DateUtil.getDateBeforeWeek(new Date()));
        String endDate = DateUtil.getStrDate(-1, new Date(), dataFormat);
        if (endDate.equals(endTime) && beginDate.equals(startTime) && 1 == param.getCurrentPage()
                && StringUtils.isBlank(param.getCategoryId())) {
            return true;
        }
        return false;
    }

    /**
     * 查询产品当年评论趋势
     *
     * @param productId 产品id
     * @return 结果集json数组
     */
    @ResponseBody
    @RequestMapping(value = "selectCommentTendency", method = RequestMethod.GET)
    public List<CommentTendencyResponse> selectCommentTendency(String productId) {
        log.info("request selectCommentTendency start.");
        List<CommentTendencyResponse> result = new ArrayList<>();
        try {
            result = productAnalysisService.selectProductCurrentYearCommentTendency(productId);
        } catch (Exception e) {
            log.error("request selectCommentTendency error:" + e.getMessage(), e);
        }
        log.info("request selectCommentTendency end.");
        return result;
    }

    /**
     * 查询产品的热词排行
     *
     * @param productId 产品id
     * @return 结果的json
     */
    @ResponseBody
    @RequestMapping(value = "selectProductViewPointRank", method = RequestMethod.GET)
    public ProductViewPointRankResponse selectProductViewPointRank(String productId) {
        log.info("request selectProductViewPointRank start.");
        ProductViewPointRankResponse response = null;
        try {
            ProductViewPointRankQuery query = new ProductViewPointRankQuery();
            query.setProductId(productId);
            response = productAnalysisService.selectProductViewPointRank(query);
        } catch (Exception e) {
            log.error("request selectProductViewPointRank error:" + e.getMessage(), e);
        }
        log.info("request selectProductViewPointRank end.");
        return response;
    }

    @RequestMapping("detail")
    public String detail(ModelMap model, Long productId, String productName, String flag,
                         String pcategoryId, String psentiment, String ptags, String choose_date,
                         String pcategoryName, String timeLabel, String ocategoryId, String categoryId,
                         String overviewDay, String selectedTime, String isocategory, String isbackbtn) {
        model.addAttribute("productId", productId);
        model.addAttribute("productName", productName);
        model.addAttribute("flag", flag);
        model.addAttribute("pcategoryId", pcategoryId);
        model.addAttribute("psentiment", psentiment);
        model.addAttribute("ptags", ptags);
        model.addAttribute("choose_date", choose_date);
        model.addAttribute("pcategoryName", pcategoryName);
        model.addAttribute("timeLabel", timeLabel);
        model.addAttribute("overviewDay", overviewDay);
        model.addAttribute("ocategoryId", ocategoryId);
        model.addAttribute("categoryId", categoryId);
        model.put("selectedTime", selectedTime);
        model.put("categoryId", categoryId);
        model.addAttribute("isocategory", isocategory);
        model.addAttribute("isbackbtn", isbackbtn);
        return "application/productComment/detail";
    }

    @RequestMapping("productSort")
    public String productSort(ModelMap model, ProductRankPageQuery query, String choose_date,
                              String categoryId, String flag, String selectedTime, String procategoryId) {
        EnumForCategory[] categories = EnumForCategory.getAllCategory();
        model.put("categories", categories);
        model.put("choose_date", choose_date);
        model.put("categoryId", categoryId);
        model.put("flag", flag);
        model.put("selectedTime", selectedTime);
        model.put("procategoryId", procategoryId);
        if (StringUtils.isBlank(query.getOrderBy())) {
            query.setOrderBy("good desc");
        }
        return "application/productComment/productSort";
    }

    //    查询某一产品的好评评价词
    @ResponseBody
    @RequestMapping(value = "goodView", method = RequestMethod.GET)
    public Map<String, Object> goodView(ProductCommentDetail productCommentDetail, Long productId,
                                        String chooseTime, String categoryId) {
        List<ProductCommentDetail> goodView = new ArrayList<>();
        Map<String, Object> resultMap = new HashMap<>();
        String beginDate = null;
        String endDate = null;
        try {
            if (!StringUtils.isEmpty(chooseTime)) {
                Map<String, Date> map = DateUtil.getSelectDate(chooseTime);
                beginDate = new SimpleDateFormat("yyyy/MM/dd").format(map.get("beginDate"));
                endDate = new SimpleDateFormat("yyyy/MM/dd").format(map.get("endDate"));
            }
            goodView = productCommentDetailService.selectGoodViewpoint(productCommentDetail, productId, beginDate, endDate, categoryId);
            resultMap.put("goodView", goodView);
            // 获取好评观点排名前十
            List<ProductCommentDetail> preGoodView = new ArrayList<>();
            if (!CollectionUtils.isEmpty(goodView)) {
                int viewNum = goodView.size() >= 10 ? 10 : goodView.size();
                for (int i = 0; i < viewNum; i++) {
                    preGoodView.add(goodView.get(i));
                }
            }
            resultMap.put("preGoodView", preGoodView);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultMap;
    }


    //查询某一产品的差评评价词
    @RequestMapping(value = "badView", method = RequestMethod.GET)
    @ResponseBody
    public Map<String, Object> badView(ProductCommentDetail productCommentDetail, Long productId,
                                       String chooseTime, String categoryId) {
        List<ProductCommentDetail> badView = new ArrayList<>();
        Map<String, Object> resultMap = new HashMap<>();
        String beginDate = null;
        String endDate = null;
        try {
            if (!StringUtils.isEmpty(chooseTime)) {
                Map<String, Date> map = DateUtil.getSelectDate(chooseTime);
                beginDate = new SimpleDateFormat("yyyy/MM/dd").format(map.get("beginDate"));
                endDate = new SimpleDateFormat("yyyy/MM/dd").format(map.get("endDate"));
            }
            badView = productCommentDetailService.selectBadViewpoint(productCommentDetail,
                    productId, beginDate, endDate, categoryId);
            resultMap.put("badView", badView);
            // 获取差评观点排名前十
            List<ProductCommentDetail> preBadView = new ArrayList<>();
            if (!CollectionUtils.isEmpty(badView)) {
                int viewNum = badView.size() >= 10 ? 10 : badView.size();
                for (int i = 0; i < viewNum; i++) {
                    preBadView.add(badView.get(i));
                }
            }
            resultMap.put("preBadView", preBadView);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return resultMap;
    }

    /**
     * @param @param  choose_date
     * @param @param  senseType
     * @param @return 设定文件
     * @return Map<String,Object> 返回类型
     * @throws
     * @Title: productRank
     * @Description: 产品评价排名
     */
    @RequestMapping("productRank")
    @ResponseBody
    public Map<String, Object> productRank(ModelMap model, ProductRankPageQuery query, String choose_date,
                                           String categoryId, String flag, String currentPage, String pageSize) {
        Map<String, Object> resultMap = new HashMap<>();
        log.info("productComment productRank start");
        try {
            JSONArray barData1 = JSONArray.fromObject(
                    getProductData(choose_date, "2", categoryId, flag, currentPage, pageSize));
            JSONArray barData2 = JSONArray.fromObject(
                    getProductData(choose_date, "0", categoryId, flag, currentPage, pageSize));
            EnumForCategory[] categories = EnumForCategory.getAllCategory();
            resultMap.put("barData1", barData1);
            resultMap.put("barData2", barData2);
            model.put("categories", categories);
        } catch (Exception e) {
            log.error("productComment productRank error:" + e.getMessage(), e);
            e.printStackTrace();
        }
        log.info("productComment productRank end");
        return resultMap;
    }

    /**
     * @param @param  choose_date
     * @param @param  sense_type
     * @param @return 设定文件
     * @return JSONArray 返回类型
     * @throws
     * @Title: getProductData
     * @Description: 获取好评差评排名前十的产品
     */


    private JSONArray getProductData(String choose_date, String sense_type, String categoryId, String flag,
                                     String currentPage, String pageSize) {

        JSONArray barData = new JSONArray();
        String productInfoStr;
        ProductRankPageQuery param = new ProductRankPageQuery();
        try {
            String key = redisService.getKey("productRank_" + sense_type);
            // 封装参数
            param.setStartTime(DateUtil.getQueryDate(choose_date).get("beginDate"));
            param.setEndTime(DateUtil.getQueryDate(choose_date).get("endDate"));
            param.setCommentType(sense_type);
            param.setCategoryId(categoryId);
            param.setFlag(flag);
            param.setCurrentPage(Integer.parseInt(currentPage));
            param.setPageSize(Integer.parseInt(pageSize));

            if (isProductRankQueryRedis(param)) {
                log.info("productComment productRank getProductData redis query start");
                productInfoStr = redisService.getObjectValue(key);
                log.info("productComment productRank getProductData redis query end");
                if (StringUtils.isNotBlank(productInfoStr)) {
                    barData = new Gson().fromJson(productInfoStr, new TypeToken<JSONArray>() {}.getType());
                } else {
                    log.info("productComment productRank getProductData mysql query start");
                    barData = queryProductData(param);
                    redisService.setValueExpire(key, barData, Constants.TIMEOUT);
                    log.info("productComment productRank getProductData mysql query end");
                }
            } else {
                barData = queryProductData(param);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("productComment productRank getProductData redis error :" + e.getMessage(), e);
            try {
                log.info("productComment productRank getProductData mysql requery start");
                barData = queryProductData(param);
                log.info("productComment productRank getProductData mysql requery end");
            } catch (Exception e1) {
                e1.printStackTrace();
                log.error("productComment productRank getProductData mysql requery error" + e1.getMessage(), e1);
            }
        }
        return barData;
    }

    /**
     * 查询产品评价排名
     * @param param
     * @return
     */
    private JSONArray queryProductData(ProductRankPageQuery param) {
        log.info("productComment productRank queryProductData query start");
        JSONArray array = productAnalysisService.getProductSortRank(param);
        log.info("productComment productRank queryProductData query end");
        return array;
    }

}
